package com.ymk.cmd;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ymk.base.cmd.ACmd;
import com.ymk.base.cmd.CmdSign;
import com.ymk.base.exception.MallException;
import com.ymk.base.service.WxService;
import com.ymk.base.utlis.ParamsBuilder;
import com.ymk.bo.user.UserInfoBO;
import com.ymk.core.code.cmd.UserCmdCode;
import com.ymk.core.constants.WxConstants;
import com.ymk.service.IUserInfoService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Objects;


/**
 * 抖音小程序获取手机号
 */
@Service
public class UserPhoneGetDYCmd extends ACmd {
    @Override
    public CmdSign executeMop(HttpServletRequest request, CmdSign sign) throws Exception {
        CmdSign respSign = new CmdSign(sign);
        UserInfoBO reqData = super.getData(sign, UserInfoBO.class);
        String openId = request.getHeader(WxConstants.X_WX_OPENID);

        ParamsBuilder paramsBuilder = ParamsBuilder.newBuild()
                .addParam("wxOpenId", openId)
                .setReturnStruct(sign.getReturnStruct());
        UserInfoBO respData = this.userService.get(paramsBuilder.build());
        if(Objects.isNull(respData)){
            throw new MallException("该用户不存在");
        }


       String mobile = this.getPhoneNumber(reqData.getReqCode(),reqData.getSessionKey(),reqData.getIv());
        respData.setMobile(mobile);
        this.setModifiedData(sign,respData);
        userService.update(respData);
        UserInfoBO userInfoBO = new UserInfoBO();
        userInfoBO.setReqCode(respData.getReqCode());
        userInfoBO.setMobile(respData.getMobile());
        respSign.setSource(super.getSource(userInfoBO));

        return respSign;
    }

    @Override
    public CmdSign executeSop(HttpServletRequest request, CmdSign sign) throws Exception {
        CmdSign respSign = new CmdSign(sign);
        UserInfoBO reqData = super.getData(sign, UserInfoBO.class);

        ParamsBuilder paramsBuilder = ParamsBuilder.newBuild()
                .addParam("userId", reqData.getUserId())
                .addParam("sessionKey",true)
                .setReturnStruct(sign.getReturnStruct());
        UserInfoBO respData = this.userService.get(paramsBuilder.build());
        if(Objects.isNull(respData)){
            throw new MallException("该用户不存在");
        }

        String mobile = this.getPhoneNumber(reqData.getReqCode(),respData.getSessionKey(),reqData.getIv());
        respData.setMobile(mobile);
        this.setModifiedData(sign,respData);
        userService.update(respData);
        respSign.setSource(super.getSource(respData));


        return respSign;
    }

    private String getPhoneNumber(String encryptedData, String sessionKey, String iv) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] sessionKeyBytes = decoder.decode(sessionKey);
        byte[] ivBytes = decoder.decode(iv);
        byte[] encryptedBytes = decoder.decode(encryptedData);

        // JDK does not support PKCS7Padding, use PKCS5Padding instead
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec skeySpec = new SecretKeySpec(sessionKeyBytes, "AES");
        IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
        byte[] ret = cipher.doFinal(encryptedBytes);
        JSONObject json = JSONObject.parseObject(new String(ret));
        return json.getString("phoneNumber");
    }


    @Override
    public String getCmdCode() {
        return UserCmdCode.USER_PHONE_GET_DY;
    }

    @Override
    public CmdSign verify(HttpServletRequest request, CmdSign sign) throws Exception {
        UserInfoBO reqData = super.getData(sign, UserInfoBO.class);

        if(StringUtils.isBlank(reqData.getReqCode())){
            throw new MallException("请求reqCode不能为空");
        }
        if(StringUtils.isBlank(reqData.getIv())){
            throw new MallException("请求iv不能为空");
        }
        return null;
    }
    @Override
    public boolean anon(CmdSign sign) {
        return true;
    }

    @Autowired
    private WxService wxService;

    @Autowired
    private IUserInfoService userService;
}
